/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sync.merge;

import autoUpdate.UpdateManager;
import java.util.logging.Level;
import java.util.logging.Logger;
import sync.exceptions.MergeException;

/**
 *
 * @author zalem1
 */
public class MergeChangesThread extends Thread {

    private MergeManager _manager;
    private boolean _enabled = true;

    public MergeChangesThread(MergeManager manager) {
        _manager = manager;
    }

    @Override
    public void run() {
        while (_enabled) {
            runUpdate();
        }
    }
        
    private void runUpdate() {
        WatchEntry watchEntry = _manager.getMergeEntry();

        MergeAction action = MergeAction.UP_TO_DATE;
        try {
            action = CompareMedia(watchEntry);
        } catch (Exception ex) {
            Logger.getLogger(MergeChangesThread.class.getName()).log(Level.SEVERE, null, ex);
            return;
        }

        switch (action) {
            case UPDATE_LOCAL:
                try {
                    watchEntry.copyOnlineToLocal(true);
                    watchEntry.updateMetadata();
                } catch (MergeException ex) {
                    Logger.getLogger(MergeChangesThread.class.getName()).log(Level.SEVERE, null, ex);
                }
                break;
            case DELETE_LOCAL:
                try {
                    watchEntry.deleteMedia();
                    Logger.getLogger(MergeChangesThread.class.getName()).log(Level.INFO, "Removed local picture {0}", watchEntry.getFilename());
                } catch (MergeException ex) {
                    Logger.getLogger(MergeChangesThread.class.getName()).log(Level.SEVERE, null, ex);
                }
                break;
            case UPDATE_ONLINE:
                try {
                    watchEntry.copyLocalToOnline(true);
                    watchEntry.updateMetadata();
                    Logger.getLogger(MergeChangesThread.class.getName()).log(Level.SEVERE, "Action UPDATE_ONLINE is not yet implemented");
                } catch (MergeException ex) {
                    Logger.getLogger(MergeChangesThread.class.getName()).log(Level.SEVERE, null, ex);
                }                                
                break;
            case DELETE_ONLINE:
                try {
                    watchEntry.deleteMedia();
                    Logger.getLogger(MergeChangesThread.class.getName()).log(Level.SEVERE, "Action DELETE_ONLINE is not yet implemented");
                } catch (MergeException ex) {
                    Logger.getLogger(MergeChangesThread.class.getName()).log(Level.SEVERE, null, ex);
                }                
                break;
            case MERGE:
                Logger.getLogger(MergeChangesThread.class.getName()).log(Level.SEVERE, "Action MERGE is not yet implemented");
                break;
            case ERROR:
                Logger.getLogger(MergeChangesThread.class.getName()).log(Level.INFO, "Unexpected error while trying to synchronise file", watchEntry.getFilename());
                break;
            case UP_TO_DATE:
                Logger.getLogger(MergeChangesThread.class.getName()).log(Level.SEVERE, "Action UP_TO_DATE is not yet implemented");
                break;

        }


    }

    private MergeAction CompareMedia(WatchEntry watchEntry) throws MergeException {
        String photoFilename = watchEntry.getFilename();

        //handles updates
        if (watchEntry.isNew()) {
            //Both online and local files exist
            if (watchEntry.existsLocally() && watchEntry.existsOnline()) {
                if (!watchEntry.changedLocally() && !watchEntry.changedOnline()) {
                    Logger.getLogger(UpdateManager.class.getName()).log(Level.INFO, "Photo {0} exists in DB, locally and online; no changes online and locally; Action: None", photoFilename);
                    return MergeAction.UP_TO_DATE;
                } else if (!watchEntry.changedLocally() && watchEntry.changedOnline()) {
                    Logger.getLogger(UpdateManager.class.getName()).log(Level.INFO, "Photo {0} exists in DB, locally and online; changes online but not locally; Action: Update Local", photoFilename);
                    return MergeAction.UPDATE_LOCAL;
                } else if (watchEntry.changedLocally() && !watchEntry.changedOnline()) {
                    Logger.getLogger(UpdateManager.class.getName()).log(Level.INFO, "Photo {0} exists in DB, locally and online; changes locally but not online; Action: Update Online", photoFilename);
                    return MergeAction.UPDATE_ONLINE;
                } else if (watchEntry.changedLocally() && watchEntry.changedOnline()) {
                    Logger.getLogger(UpdateManager.class.getName()).log(Level.INFO, "Photo {0} exists in DB, locally and online; changes locally and online; Action: Merge", photoFilename);
                    return MergeAction.MERGE;
                }
                //file removed locally
            } else if (!watchEntry.existsLocally() && watchEntry.existsOnline()) {
                if (!watchEntry.changedOnline()) {
                    Logger.getLogger(UpdateManager.class.getName()).log(Level.INFO, "Photo {0} exists in DB and online but doesn't exist locally; it was not changed online; Action: Delete online", photoFilename);
                    return MergeAction.DELETE_ONLINE;
                } else {
                    Logger.getLogger(UpdateManager.class.getName()).log(Level.INFO, "Photo {0} exists in DB and online but doesn't exist locally; it was changed online; Action: Merge", photoFilename);
                    return MergeAction.MERGE;
                }
                //removed online
            } else if (watchEntry.existsLocally() && !watchEntry.existsOnline()) {
                if (!watchEntry.changedLocally()) {
                    Logger.getLogger(UpdateManager.class.getName()).log(Level.INFO, "Photo {0} exists in DB and locally but doesn't exist online; it was not changed locally; Action: Delete Local", photoFilename);
                    return MergeAction.DELETE_LOCAL;
                } else {
                    Logger.getLogger(UpdateManager.class.getName()).log(Level.INFO, "Photo {0} exists in DB and locally but doesn't exist online; it was changed locally; Action: Merge", photoFilename);
                    return MergeAction.MERGE;
                }
                //database out of date
            } else if (!watchEntry.existsLocally() && !watchEntry.existsOnline()) {
                Logger.getLogger(UpdateManager.class.getName()).log(Level.INFO, "Photo {0} exists in DB only; Action: None", photoFilename);
                return MergeAction.UP_TO_DATE;
            }
        } //handles initial download
        else if (!watchEntry.isNew()) {
            if (watchEntry.existsLocally() && watchEntry.existsOnline()) {
                //download full-ress photo and compare to the local
                if (watchEntry.compareLocalToOnline()) {
                    //ToDo: update DB
                    Logger.getLogger(UpdateManager.class.getName()).log(Level.INFO, "Photo {0} doesn't exist in DB but exist locally and online. Local copy matches online version; Action: None", photoFilename);
                    return MergeAction.UP_TO_DATE;
                } else {
                    Logger.getLogger(UpdateManager.class.getName()).log(Level.INFO, "Photo {0} doesn't exist in DB but exist locally and online. Local copy doesn't matche online version; Action: Merge", photoFilename);
                    return MergeAction.MERGE;
                }
            }

            //initial download of the new online file
            if (watchEntry.existsOnline() && !watchEntry.existsLocally()) {
                Logger.getLogger(UpdateManager.class.getName()).log(Level.INFO, "Photo {0} doesn't exist in DB and locally but exist online; Action: Update Local", photoFilename);
                return MergeAction.UPDATE_LOCAL;
            }

            //initial upload of the new local file
            if (!watchEntry.existsOnline() && watchEntry.existsLocally()) {
                Logger.getLogger(UpdateManager.class.getName()).log(Level.INFO, "Photo {0} doesn't exist in DB and online but exist locally; Action: Update Online", photoFilename);
                return MergeAction.UPDATE_ONLINE;
            }
        }


        Logger.getLogger(UpdateManager.class.getName()).log(Level.SEVERE, "Exiting through last chance return statement. This could indicate bug.");
        return MergeAction.UP_TO_DATE;

    }
}
